package com.mobimagic.lockscreen.view;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;

import com.mobimagic.lockscreen.R;
import com.mobimagic.lockscreen.sdk.ILockScreenBooster;
import com.mobimagic.lockscreen.sdk.LockScreenSDK;
import com.mobimagic.lockscreen.util.ScreenUtil;
import com.mobimagic.lockscreen.util.WeakHandler;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.Animator.AnimatorListener;
import com.nineoldandroids.animation.AnimatorSet;
import com.nineoldandroids.animation.ObjectAnimator;

public class MagicLayout extends FrameLayout {
    private View mCenterlayout;
    private ImageView mMagicDoor, mMagicBg;
    private Animation mRoateAnimation;
    private static long ANIMATION = 500;//吸入动画的时间
    private static int LOAD_DELAY = 50;//加载延时
    private static int IMAGE_SIZE = 50;//吸入动画的imageview的宽高

    private int index = 0;
    private List<String> pkgList;
    private ILockScreenBooster mLockScreenBooster;
    private int showIndex = 0;
    public static final ExecutorService mLoadProcessExecutors = Executors.newFixedThreadPool(4);
    private WeakHandler mWeakHandler;
    private boolean isStop = false;

    public MagicLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        mWeakHandler = new WeakHandler();
        mLockScreenBooster = LockScreenSDK.getInstance().getLockScreenBooster();
        mRoateAnimation = new RotateAnimation(360f, 0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        mRoateAnimation.setDuration(ANIMATION);
        mRoateAnimation.setRepeatCount(-1);
        mRoateAnimation.setInterpolator(new LinearInterpolator());
    }

    public void setPkgList(List<String> pkgList) {
        isStop = false;
        this.pkgList = pkgList;
        startDoorAnimation();
        load(false);
    }

    class LoadTask extends AsyncTask<Void, Void, Drawable> {
        long coastTime = 0;

        public LoadTask() {

        }

        @Override
        protected Drawable doInBackground(Void... params) {
            Drawable processIcon = null;
            if (pkgList != null && !pkgList.isEmpty()) {
                try {
                    long beinTim = System.currentTimeMillis();
                    int size = pkgList.size();
                    int location = showIndex % size;
                    showIndex++;
                    String pkg = pkgList.get(location);
                    processIcon = mLockScreenBooster.getPkgDrawable(pkg);
                    coastTime = System.currentTimeMillis() - beinTim;
                } catch (Exception e) {

                }

            }
            return processIcon;
        }

        @Override
        protected void onPostExecute(Drawable result) {
            super.onPostExecute(result);
            if (isStop) {
                return;
            }
            if (result != null) {
                startAnimation(getImageView(result));
            }
            if (coastTime < LOAD_DELAY) {
                load(true);
            } else {
                load(false);
            }

        }

    }

    private void load(boolean isDelay) {
        if (isStop) {
            return;
        }
        if (isDelay) {
            mWeakHandler.postDelayed(new LoadRunnbale(), LOAD_DELAY);
        } else {
            mWeakHandler.post(new LoadRunnbale());
        }
    }

    class LoadRunnbale implements Runnable {

        @Override
        public void run() {
            LoadTask task = new LoadTask();
            if (Build.VERSION.SDK_INT < 11) {
                task.execute();
            } else {
                task.executeOnExecutor(mLoadProcessExecutors);
            }
        }
    }

    public void onDesotry() {
        isStop = true;
        mWeakHandler.removeCallbacks(null);
        stopDoorAnimation();
    }

    private void startAnimation(final ImageView im) {
        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) im.getLayoutParams();
        int width = params.width;
        int height = params.height;
        float toXDelta = (getWidth() - width) / 2;
        float toYDelta = (getHeight() - height) / 2;
        int[] xy = getXY(params);

        ObjectAnimator x = ObjectAnimator.ofFloat(im, "translationY", xy[0], toXDelta);
        ObjectAnimator y = ObjectAnimator.ofFloat(im, "translationX", xy[1], toYDelta);
        ObjectAnimator alpha = ObjectAnimator.ofFloat(im, "alpha", 1f, 0);
        ObjectAnimator scaleX = ObjectAnimator.ofFloat(im, "scaleX", 1f, 0);
        ObjectAnimator scaleY = ObjectAnimator.ofFloat(im, "scaleY", 1f, 0);
        AnimatorSet set = new AnimatorSet();
        set.play(x);
        set.play(y);
        set.play(alpha);
        set.play(scaleX);
        set.play(scaleY);
        set.setDuration(ANIMATION);
        set.start();
        set.addListener(new AnimatorListener() {
            @Override
            public void onAnimationStart(Animator arg0) {
            }

            @Override
            public void onAnimationRepeat(Animator arg0) {
            }

            @Override
            public void onAnimationEnd(Animator arg0) {
                if (im != null) {
                    im.setVisibility(View.GONE);
                    removeView(im);
                }

            }

            @Override
            public void onAnimationCancel(Animator arg0) {
                if (im != null) {
                    im.setVisibility(View.GONE);
                    removeView(im);
                }
            }
        });

    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mCenterlayout = findViewById(R.id.magic_center_layout);
        mMagicDoor = (ImageView) findViewById(R.id.magic_door);
        mMagicBg = (ImageView) findViewById(R.id.magic_bg);
    }

    public ImageView getImageView(Drawable drawable) {
        int size = (int) ScreenUtil.dpToPx(getContext(), IMAGE_SIZE);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(size, size);
        ImageView im = new ImageView(getContext());
        im.setScaleType(ScaleType.FIT_XY);
        if (drawable != null) {
            im.setImageDrawable(drawable);
        }
        addView(im, params);
        return im;
    }

    private int[] getXY(FrameLayout.LayoutParams params) {
        int postion = index % 4;
        index++;
        int[] xy = new int[2];
        int centerHeight = mCenterlayout.getHeight();
        int centerWidth = mCenterlayout.getWidth();
        int height = getHeight();
        int width = getWidth();
        int marginW = (width - centerWidth) / 2;
        int marginH = (height - centerHeight) / 2;
        int viewWidth = params.width;
        int viewHight = params.height;
        if (postion == 0) {
            int maxX = marginW + centerWidth;
            int maxY = marginH;
            int x = (int) (Math.random() * Math.max(0, maxX - viewWidth));
            int y = (int) (Math.random() * maxY);
            xy[0] = x;
            xy[1] = y;
        } else if (postion == 1) {
            int maxX = marginW + viewWidth;
            int maxY = marginH + centerHeight;
            int x = Math.min(width - (int) (Math.random() * maxX), width - viewWidth);
            int y = Math.min((int) (Math.random() * maxY), height - viewHight);
            xy[0] = x;
            xy[1] = y;
        } else if (postion == 2) {
            int maxX = marginW + centerWidth;
            int maxY = marginH;
            int x = marginW + (int) (Math.random() * maxX) - viewWidth;
            int y = height - (int) (Math.random() * maxY) - viewHight;
            xy[0] = x;
            xy[1] = y;
        } else if (postion == 3) {
            int maxX = marginW;
            int maxY = marginH + centerHeight;
            int x = (int) (Math.random() * maxX);
            int y = Math.min((int) (Math.random() * maxY), height - viewHight);
            xy[0] = x;
            xy[1] = y;
        }
        return xy;
    }

    private void startDoorAnimation() {
        if (mMagicDoor != null && mRoateAnimation != null) {
            mMagicDoor.startAnimation(mRoateAnimation);
        }
    }

    private void stopDoorAnimation() {
        if (mMagicDoor != null) {
            mMagicDoor.clearAnimation();
        }
    }

}
